/*
 * @Description: 路由权限守卫
 * @Author: qingyang
 * @Date: 2023-01-12 14:33:15
 * @LastEditors: qingyang
 * @LastEditTime: 2023-06-28 16:29:54
 */
import type { Router, RouteLocationNormalized, NavigationGuardNext } from 'vue-router';
import { useAboutLogin } from '@/hooks/useAboutLogin';
import { useRouterSubApp } from '@/commonModule/hooks/useRouterSubApp';
import { userSelfConfig } from './userSelfConfig';
import { store } from '@/store';
import auth from '@/utils/auth';
import { AppMutationTypes } from '@/store/modules/app/mutation-types';
import { UserActionTypes } from '@/store/modules/user/action-types';
import { resetRouter } from '@/router';
export const createPermissionGuard = (router: Router) => {
  const { handleJumpWithToken } = useAboutLogin();
  const { routerToCoLogin } = useRouterSubApp();
  const { WHITE_NAME_LIST, CONSTANT_ROUTES } = userSelfConfig();
  router.beforeEach(
    async (
      to: RouteLocationNormalized,
      from: RouteLocationNormalized,
      next: NavigationGuardNext
    ) => {
      // 如果路由跳转到登录页
      if (to.path === '/login') {
        // 如果说url中带有登录token，则为第一优先级，不管之前有没有登录，是以何种方式登录，都覆盖
        const flag = handleJumpWithToken(to);
        if (flag) {
          return next();
        }
      }
      const hasToken = getHasToken();
      if (hasToken) {
        if (to.path === '/login') {
          return next({ path: '/' });
        }
        // 判断是否已经得到用户数据
        const hasUserId = store.state.user.userInfo?.userId;
        if (hasUserId) {
          checkMenuList(to, from, next);
        } else {
          try {
            // 获取角色权限
            const roles = await store.dispatch(UserActionTypes.ACTION_CHANGE_ROLES);
            // NOTE 供应商端不处理权限
            if (store.state.user.userType === 'SUPPLIER') {
              //检查页面是否需要keep alive
              handleCheckKeepAlive(to, from);
              return next();
            }
            await store.dispatch(UserActionTypes.ACTION_SET_ROUTES, roles);
            resetRouter();
            store.state.user.routes.forEach(route => {
              router.addRoute('Layout', route);
            });
            checkMenuList(to, from, next);
          } catch (error) {
            console.log('路由切换 没有获取过权限 error', error);
            auth.clearUserInfo();
            auth.clearLoginInfo();
            return routerToCoLogin(encodeURIComponent(to.fullPath), next);
          }
        }
      } else {
        //没有token的情况去校验是否是白名单
        if (WHITE_NAME_LIST.includes(to.path)) {
          return next();
        } else {
          // 跳转到登录页并附带想要访问的地址
          return routerToCoLogin(encodeURIComponent(to.fullPath), next);
        }
      }
    }
  );
  const checkConstantRoutesInclude = (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    console.log('路由切换 检查是否固定路由');
    handleCheckKeepAlive(to, from);
    if (CONSTANT_ROUTES.includes(to.path)) {
      console.log('路由切换 检查是否固定路由 是', to.path);
      return next();
    } else {
      console.log('路由切换 检查是否固定路由 否 跳转到401', to.path);
      return next('/401');
    }
  };
  const checkMenuList = (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    const menuList = store.state.user.menuList;
    if (menuList && menuList.length) {
      const menuPathList = [...new Set(menuList.map(item => item.redirect || item.path))];
      const toPath = to.meta?.selectKeysPath ?? to.path;
      if (menuPathList.includes(toPath)) {
        // 路由包含在菜单列表里
        //检查页面是否需要keep alive
        handleCheckKeepAlive(to, from);
        return next();
      } else {
        checkConstantRoutesInclude(to, from, next);
      }
    } else {
      checkConstantRoutesInclude(to, from, next);
    }
  };
  // 获取token
  const getHasToken = (): boolean => {
    const token = localStorage.getItem('token');
    if (token === 'refreshing') return false;
    return Boolean(token);
  };

  /**
   * 检查页面是否需要keepalive
   * @param to
   * @param from
   */
  function handleCheckKeepAlive(to: RouteLocationNormalized, from: RouteLocationNormalized) {
    const toName = to.name;
    const fromName = from.name as string;
    const toKeepAlive = to.meta?.keepAlive;
    const fromKeepAlive = from.meta?.keepAlive;
    const toParentName = to.meta?.keepAliveParentName;
    const fromParentName = from.meta?.keepAliveParentName;
    console.log('handleCheckKeepAlive', toParentName, fromParentName);
    // 去的页面是keepalive的
    if (toKeepAlive === true) {
      // 设置keepAlive
      if (store.state.app.removeAliveFlag) {
        store.commit(AppMutationTypes.REMOVE_KEEP_ALIVE, toName);
      } else {
        store.commit(AppMutationTypes.SET_KEEP_ALIVE, toName);
      }
    }
    // NOTE 目前仅支持列表跳转详情这类的keepAlive形式
    // 切换路由不是当前keepAlive页面的子页面时，去除当前keepAlive页面的keepAlive属性
    if (fromKeepAlive === true && toParentName !== fromName) {
      if (!(typeof toParentName === 'object' && toParentName?.includes(fromName))) {
        store.commit(AppMutationTypes.REMOVE_KEEP_ALIVE, fromName);
      }
    }

    // 当前路由是keepAlive页面的子页面，并且将要跳转的页面不是此keepAlive页面时，去除此keepAlive页面的keepAlive属性
    if (fromKeepAlive !== true && fromParentName && fromParentName !== toName) {
      console.log('handleCheckKeepAlive 子页面跳转', fromParentName, toName);
      if (typeof fromParentName === 'object') {
        console.log('typeof fromParentName === object', fromParentName);
        for (let i = 0; i < fromParentName?.length; i++) {
          const item = fromParentName[i];
          if (item !== toName) {
            store.commit(AppMutationTypes.REMOVE_KEEP_ALIVE, item);
          }
        }
      } else {
        store.commit(AppMutationTypes.REMOVE_KEEP_ALIVE, fromParentName);
      }
    }
  }
};
